package cn.cai.controller;

import cn.cai.pojo.*;
import cn.cai.service.BasicInformationService;
import cn.cai.service.EmailService;
import cn.cai.service.ReportLogService;
import cn.cai.service.ReportPeace;
import cn.cai.utils.RedisCache;
import cn.cai.utils.SpringUtil;
import cn.cai.utils.TimeUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;


/**
 * 关于服务器向目标服务器请求的控制器
 */
@Component
@Slf4j
public class RequestController {
    @Autowired
    private ReportPeace reportPeace;
    @Autowired
    private BasicInformationService basicInformationService;
    @Autowired
    private EmailService emailService;
    @Autowired
    private ReportLogService reportLogService;
    @Autowired
    private RedisTemplate<Object, Object> redisTemplate;

    @Autowired
    private RedisCache redisCache;

    /**
     * 每30秒遍历任务一次，从中找出符合的任务要求
     */
    @SneakyThrows
    @Scheduled(cron = "0/5 * * * * ?")
    public void task(){
        // 从内存中allTask队列的左边取出一条数据
        Object itemObject =  redisTemplate.opsForList().leftPop("allTask");
        if (ObjectUtils.isEmpty(itemObject)){
            log.info("无任务");
        }else {
            JSONObject jsonObject = JSON.parseObject(itemObject.toString());
            BasicInformation item = jsonObject.toJavaObject(BasicInformation.class);
            // 判断时间是否达到了发送条件
            if (TimeUtil.judgment(item.getReportingTime())) {
                log.info("学号{}：时间上符合",item.getXh());
                item.setSbsj(LocalDateTime.now());
                Parameter parameter = new Parameter();
                BeanUtils.copyProperties(item, parameter);
                ResponseData responseData = reportPeace.sendParamForPost(parameter);
                if (ObjectUtils.isEmpty(responseData)) {
                    // 目标服务器无法响应
                    reportLogService.addLog(new ReportLog(null, parameter.getXh(), parameter.getSbsj(), LocalDateTime.now(), "服务器无响应"));
                    // 将取出的数据放到allTask队列的右边
                    redisTemplate.opsForList().rightPush("allTask", item);
                    log.info("服务器无响应");
                }
                if (responseData.getMessage().equals("成功")) {
                    // 查询报平安的数据
                    List<QueryData> list = reportPeace.queryDataForGet(item.getXh());
                    // 将信息发送给对应的人
                    emailService.sendEmali(item.getMail(), parameter, list);
                    // 向数据库中添加日志
                    reportLogService.addLog(new ReportLog(null, parameter.getXh(), parameter.getSbsj(), LocalDateTime.now(), "成功"));
                    log.info("{}，任务完成，任务删除", item);
                }
                if (responseData.getMessage().equals("不能重复上报!")) {
                    // 查询报平安的数据
                    List<QueryData> list = reportPeace.queryDataForGet(item.getXh());
                    emailService.sendRepeat(item.getMail(), responseData, list);
                    // 向数据库中添加日志
                    reportLogService.addLog(new ReportLog(null, parameter.getXh(), parameter.getSbsj(), LocalDateTime.now(), "重复上报"));
                    log.info("{}重复上报，任务删除", item);
                }
            }else {
                log.info("时间不符合，将任务重新放入");
                redisTemplate.opsForList().rightPush("allTask", item);
                log.info("放入任务队列");
            }

        }

    }

    /**
     * 每天00:00执行一次，将对应的信息取出
     */
    @SneakyThrows
    @Scheduled(cron = "0 0 0 1/1 * ?")
    public void everyTask(){
        // 判断task队列中是否还有任务，如果有任务，将对应的信息和sql日志更新
        List<Object> allObjects = redisTemplate.opsForList().range("allTask", 0, -1);
        if (ObjectUtils.isEmpty(allObjects)){
            log.info("无任务");
        }else {
            List<BasicInformation> allTask = JSON.parseArray(allObjects.toString()).toJavaList(BasicInformation.class);
            log.info("更新任务列表");
            if (!ObjectUtils.isEmpty(allTask)){
                // 循环告知
                for (BasicInformation item:allTask){
                    // 重试任务
                    item.setSbsj(LocalDateTime.now());
                    Parameter parameter = new Parameter();
                    BeanUtils.copyProperties(item,parameter);
                    ResponseData responseData = reportPeace.sendParamForPost(parameter);
                    if (ObjectUtils.isEmpty(responseData)){
                        // 存储数据库日志
                        reportLogService.addLog(new ReportLog(null,item.getXh(),LocalDateTime.now(),LocalDateTime.now(),"今日报平安失败"));
                        // 发送含有错误信息的邮件致用户邮箱
                        emailService.sendEmailForError(item.getMail());
                    }else {
                        List<QueryData> list = reportPeace.queryDataForGet(item.getXh());
                        // 将成功信息发送致客户的邮箱
                        emailService.sendEmali(item.getMail(),parameter, list);
                        reportLogService.addLog(new ReportLog(null,parameter.getXh(),parameter.getSbsj(),LocalDateTime.now(),"成功"));
                    }
                }
                // 从内存中删除allTask
                redisTemplate.delete("allTask");
            }
            // 任务全部完成,重新获取新一天的数据
            List<BasicInformation> all = basicInformationService.selectAll();
            redisCache.setCacheList("allTask", all);
            log.info("新一轮的任务开始");
        }
    }

}
